using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using SolanumSolstice.Units;
using SolanumSolstice.Mapping;
using SolanumSolstice.Buildings;

namespace SolanumSolstice
{
    public class HUD
    {
        private Texture2D background;
        private Texture2D barEmpty;
        private Texture2D barFull;
        private SpriteFont font;
        private SpriteFont fontSmall;
        private Vector2 screenSize;

        private int hudHeight;
        private MiniMap miniMap;
        private List<Human> selectedUnits;
        private List<Human> activeUnits;
        private Building selectedBuilding;

        private bool mapFocusChanged;
        private Vector2 newMapFocus;
        private Random rand;

        private int maxSelection;

        private bool buttonAPressed;

        private bool groupSelect;

        #region Accessors

        public bool MapFocusChanged
        {
            get
            {
                return mapFocusChanged;
            }
            set
            {
                mapFocusChanged = value;
            }
        }

        public Vector2 NewMapFocus
        {
            get
            {
                return newMapFocus;
            }
            set
            {
                newMapFocus = value;
            }
        }

        public Building SelectedBuilding
        {
            get
            {
                return selectedBuilding;
            }
            set
            {
                selectedBuilding = value;
            }
        }

        #endregion

        public HUD(ContentManager content, Vector2 screenSize, MiniMap miniMap, int maxSelection)
        {
            background = content.Load<Texture2D>("Content\\Txtr\\Sys\\TestHUD");
            font = content.Load<SpriteFont>("Content\\Fnt\\ArialMedium");
            fontSmall = content.Load<SpriteFont>("Content\\Fnt\\ArialSmall");
            barEmpty = content.Load<Texture2D>("Content\\Txtr\\Units\\EmptyBar");
            barFull = content.Load<Texture2D>("Content\\Txtr\\Units\\FullBarWhite");
            this.screenSize = screenSize;
            hudHeight = 150;
            this.miniMap = miniMap;
            selectedUnits = new List<Human>();
            activeUnits = new List<Human>();
            mapFocusChanged = false;
            newMapFocus = new Vector2(0, 0);
            rand = new Random();
            this.maxSelection = maxSelection;
            buttonAPressed = false;
            groupSelect = false;

        }


        public void Update(GamePadState gamePad, GameCursor cursor, List<Human> units, List<Human> selectedUnits)
        {

            if (activeUnits != units)
            {
                activeUnits = units;
            }
            if (this.selectedUnits != selectedUnits)
            {
                this.selectedUnits = selectedUnits;
                selectedUnits.Sort(Human.Compare);
            }

            


            foreach (Human unit in activeUnits)
            {
                if (selectedUnits.Contains(unit))
                {
                    if (unit.IsSelected == false && unit.TargetReached == true)
                    {

                        unit.GroupOffset = new Vector2(rand.Next(10) - 5, rand.Next(5));
                    }

                    unit.IsSelected = true;

                }
                else
                {
                    unit.IsSelected = false;
                    unit.ActionSelected = false;
                }
            }





            if (gamePad.Buttons.A == ButtonState.Pressed && buttonAPressed == false)
            {


                if (cursor.ScreenPositionY > screenSize.Y - hudHeight)
                {
                    buttonAPressed = true;
                    if (cursor.ScreenPositionY >= miniMap.StartY
                        && cursor.ScreenPositionX >= miniMap.StartX
                        && cursor.ScreenPositionY < miniMap.StartY + (int)miniMap.Size.Y
                        && cursor.ScreenPositionX < miniMap.StartX + (int)miniMap.Size.X)
                    {
                        mapFocusChanged = true;
                        newMapFocus.X = ((cursor.ScreenPositionX - miniMap.StartX) * (Tile.TILEWIDTH / miniMap.ScaleSize));
                        newMapFocus.Y = ((cursor.ScreenPositionY - miniMap.StartY) * (Tile.TILEHEIGHT / miniMap.ScaleSize));
                    }

                    Human selected = null;

                        foreach (Human selUnit in selectedUnits)
                        {

                            if (cursor.ScreenPositionY >= (int)screenSize.Y - hudHeight + 40 + (int)(selectedUnits.IndexOf(selUnit) / (maxSelection / 2)) * 45
                                 && cursor.ScreenPositionX >= 20 + selectedUnits.IndexOf(selUnit) % (maxSelection / 2) * 45
                                 && cursor.ScreenPositionY < (int)screenSize.Y - hudHeight + 80 + (int)(selectedUnits.IndexOf(selUnit) / (maxSelection / 2)) * 45
                                 && cursor.ScreenPositionX < 60 + selectedUnits.IndexOf(selUnit) % (maxSelection / 2) * 45)
                            {
                                selected = selUnit;


                            }
                            


                        }
                        if (selected != null)
                        {
                            if (groupSelect == false)
                            {
                                selectedUnits.Clear();
                                selectedUnits.Add(selected);
                            }
                            else
                            {
                                UnitClass selClass = selected.UnitClass;

                                List<Unit> removeList = new List<Unit>();

                                foreach (Unit unit in selectedUnits)
                                {
                                    if (unit.UnitClass != selClass)
                                    {
                                        removeList.Add(unit);
                                    }
                                }

                                foreach (Unit rem in removeList)
                                {
                                    selectedUnits.Remove((Human)rem);
                                }
                            }
                        }

                    
                }
            }
            else
            {
                buttonAPressed = false;
            }

            if (gamePad.Triggers.Right > 0)
            {
                groupSelect = true;
            }
            else
            {
    
                groupSelect = false;

            }

        }


        public void Draw(SpriteBatch spritebatch)
        {

            spritebatch.DrawString(font, "Food: " + SolanumSolstice.GetBase().Food, new Vector2(screenSize.X - 100, 20), Color.Gold);
            spritebatch.DrawString(font, "Wood: " + SolanumSolstice.GetBase().Wood, new Vector2(screenSize.X - 100, 40), Color.Green);

            spritebatch.DrawString(font, "Human Count: " + SolanumSolstice.activeUnits.Count, new Vector2(screenSize.X - 200, screenSize.Y - hudHeight - 80), Color.White);
            spritebatch.DrawString(font, "Zombie Count: " + SolanumSolstice.activeZombies.Count, new Vector2(screenSize.X - 200, screenSize.Y - hudHeight - 60), Color.Red);
            int count = 0;

            foreach (Unit unit in SolanumSolstice.deadUnits)
            {
                if (unit.IsZombie)
                {
                    count++;
                }
            }

            spritebatch.DrawString(font, "Total Kills: " + count, new Vector2(screenSize.X - 200, screenSize.Y - hudHeight - 40), Color.Purple);
                    

            spritebatch.Draw(background, new Rectangle(0, (int)screenSize.Y - hudHeight, (int)screenSize.X, hudHeight), Color.White);

            spritebatch.DrawString(font, "Units", new Vector2(30, (int)screenSize.Y - hudHeight + 10), Color.White);

            spritebatch.DrawString(font, "Building:", new Vector2((int)(screenSize.X / 2) - 20, (int)screenSize.Y - hudHeight + 10), Color.White);

            if(selectedBuilding != null)
            {

                spritebatch.DrawString(font, selectedBuilding.Name, new Vector2((int)(screenSize.X / 2) + 70, (int)screenSize.Y - hudHeight + 10), Color.White);
                
                if (selectedBuilding.IsInfested == true)
                {
                    spritebatch.Draw(selectedBuilding.Texture, new Rectangle((int)(screenSize.X / 2) - 20, (int)screenSize.Y - hudHeight + 40, 100, 100), Color.White);

                    spritebatch.DrawString(fontSmall, "Military Left: " + selectedBuilding.Cleansers.Count, new Vector2((int)(screenSize.X / 2) + 100, (int)screenSize.Y - hudHeight + 40), Color.White);
                    spritebatch.DrawString(fontSmall, "Zombies Left: " + selectedBuilding.Zombies.Count, new Vector2((int)(screenSize.X / 2) + 100, (int)screenSize.Y - hudHeight + 60), Color.White);
                    
                }
                else
                {
                    spritebatch.Draw(selectedBuilding.Texture, new Rectangle((int)(screenSize.X / 2) - 20, (int)screenSize.Y - hudHeight + 40, 100, 100),
                        new Rectangle(0, 0, selectedBuilding.Width, selectedBuilding.Height), Color.White);

                    selectedBuilding.DrawHUD(spritebatch, new Rectangle((int)(screenSize.X / 2) + 100, (int)screenSize.Y - hudHeight + 40, 100, 100));
                }


            }


            foreach (Human unit in selectedUnits)
            {

                Color color = Color.White;
                /*
                if (unit.ActionSelected == true)
                {
                    color = Color.Yellow;
                    
                    foreach (Action action in unit.Actions)
                    {
                        Color actionColor = Color.White;

                        if (unit.CurrentActionIndex == unit.Actions.IndexOf(action))
                        {
                            actionColor = Color.Yellow;
                        }

                        spritebatch.Draw(action.HUDPicture,
                                     new Rectangle(300 + unit.Actions.IndexOf(action) % (maxSelection / 2) * 45,
                                    (int)screenSize.Y - hudHeight + 40 + (int)(unit.Actions.IndexOf(action) / (maxSelection / 2)) * 45, 40, 40), actionColor);
                    }
                     
                }
                */
                if (unit.IsDead == true)
                {
                    color = Color.Red;
                }

                spritebatch.Draw(unit.HUDTexture,
                    new Rectangle(20 + selectedUnits.IndexOf(unit) % (maxSelection / 2) * 45,
                                    (int)screenSize.Y - hudHeight + 40 + (int)(selectedUnits.IndexOf(unit) / (maxSelection / 2)) * 55, 40, 40), color);


                Color hpBar = Color.Green;;

                int hpBarLength = (int)(((float)unit.HitPoints / (float)unit.MaxHitPoints) * 40);

                if (unit.HitPoints < ((unit.MaxHitPoints * 2) / 3))
                {
                        hpBar = Color.Yellow;
                }

                if (unit.HitPoints < (unit.MaxHitPoints / 3))
                {
                        hpBar = Color.Red;
                }

                spritebatch.Draw(barEmpty, 
                    new Rectangle(20 + selectedUnits.IndexOf(unit) % (maxSelection / 2) * 45,
                                    (int)screenSize.Y - hudHeight + 80 + (int)(selectedUnits.IndexOf(unit) / (maxSelection / 2)) * 55, 40, 5), Color.White);
                spritebatch.Draw(barFull, new Rectangle(20 + selectedUnits.IndexOf(unit) % (maxSelection / 2) * 45,
                                    (int)screenSize.Y - hudHeight + 80 + (int)(selectedUnits.IndexOf(unit) / (maxSelection / 2)) * 55, hpBarLength, 5), hpBar);


                Color recoveryBar = Color.Blue;

                int recoveryBarLength = (int)(((float)unit.RecoveryTime / (float)unit.InitialRecoveryTime) * 40);

                recoveryBarLength = 40 - recoveryBarLength;

                if (recoveryBarLength == 40)
                {
                    recoveryBar = Color.GreenYellow;
                }

                spritebatch.Draw(barEmpty,
                    new Rectangle(20 + selectedUnits.IndexOf(unit) % (maxSelection / 2) * 45,
                                    (int)screenSize.Y - hudHeight + 87 + (int)(selectedUnits.IndexOf(unit) / (maxSelection / 2)) * 55, 40, 5), Color.White);
                spritebatch.Draw(barFull, new Rectangle(20 + selectedUnits.IndexOf(unit) % (maxSelection / 2) * 45,
                                    (int)screenSize.Y - hudHeight + 87 + (int)(selectedUnits.IndexOf(unit) / (maxSelection / 2)) * 55, recoveryBarLength, 5), recoveryBar);



            }




            miniMap.Draw(spritebatch, activeUnits);

        }

        public void SelectBuilding(Building building)
        {
            selectedBuilding = building;

            List<Unit> removelist = new List<Unit>();

            //Check if infested and cleanse if necessary
            if (selectedBuilding.IsInfested == true)
            {

                bool playSound = false;

                foreach (Human unit in selectedUnits)
                {
                    if (unit.UnitClass == UnitClass.Military)
                    {
                        playSound = true;
                        Cop cop = (Cop)unit;

                        cop.SetCleansingTarget(selectedBuilding.Entrance, selectedBuilding);

                        removelist.Add(unit);
                    }
                }

                if (playSound)
                {
                    SolanumSolstice.soundBank.PlayCue("cleansing");
                }
            }
            //Check if gathering building, then gather

            if (selectedBuilding.BuildingType == BuildingType.Supply)
            {

                bool playSound = false;
                foreach (Human unit in selectedUnits)
                {
                    if (unit.UnitClass == UnitClass.Civilian)
                    {
                        playSound = true;
                        Civilian civ = (Civilian)unit;

                        civ.SetGatherTarget(selectedBuilding.Entrance, selectedBuilding);

                        removelist.Add(unit);
                    }
                }

                if (playSound)
                {
                    SupplyBuilding build = (SupplyBuilding)selectedBuilding;

                    if (build.HasWood)
                    {
                        SolanumSolstice.soundBank.PlayCue("gather_wood");
                    }
                    else if (build.HasFood == true && build.HasWood == false)
                    {
                        SolanumSolstice.soundBank.PlayCue("gather_food");
                    }
                }
            }

            //Check if researchable, the research
            if (selectedBuilding.BuildingType == BuildingType.Research)
            {

                ResearchBuilding res = (ResearchBuilding)selectedBuilding;

//MAY NEED THIS                res.StartNewResearch(UnitClass.Civilian);
                bool playSound = false;

                foreach (Human unit in selectedUnits)
                {
                    if (unit.UnitClass == UnitClass.Science)
                    {
                        playSound = true;
                        Researcher sci = (Researcher)unit;

                        sci.SetResearchingTarget(selectedBuilding.Entrance, selectedBuilding);

                        removelist.Add(unit);
                    }
                }

                if (playSound)
                {
                    SolanumSolstice.soundBank.PlayCue("research_begin");
                }
            }


            foreach (Unit unit in removelist)
            {
                selectedUnits.Remove((Human)unit);
            }
        }


        public void SelectRoadBlock(RoadBlock target)
        {
            List<Human> removeList = new List<Human>();

            bool playSound = false;

            foreach (Human human in selectedUnits)
            {
                if (human.UnitClass == UnitClass.Civilian)
                {
                    playSound = true;
                    Civilian civ = (Civilian)human;

                    civ.SetRepairTarget(target);

                    removeList.Add(human);
                }
            }

            if (playSound)
            {
                SolanumSolstice.soundBank.PlayCue("Building");
            }

            foreach (Human human in removeList)
            {
                selectedUnits.Remove(human);
            }

        }
    }
}

